/* Transaction.cpp
 Michael Zahniser
 
 Function definitions for the Transaction class.
 */

#include "Transaction.h"

using std::fixed;



// Check whether this "transaction" is in fact an account modifier command.
bool Transaction::IsCommand() const
{
    return date.IsNull();
}



const Date &Transaction::GetDate() const
{
    return date;
}



void Transaction::SetDate(const Date &date)
{
    this->date = date;
}



const double Transaction::GetAmount() const
{
    return amount;
}



void Transaction::SetAmount(double amount)
{
    this->amount = amount;
}



const string &Transaction::GetFromAccount() const
{
    return from;
}



void Transaction::SetFromAccount(const string &from)
{
    this->from = from;
}



const string &Transaction::GetToAccount() const
{
    return to;
}



void Transaction::SetToAccount(const string &to)
{
    this->to = to;
}



const string &Transaction::GetComment() const
{
    return comment;
}



void Transaction::SetComment(const string &comment)
{
    this->comment = comment;
}



// Print the transaction in a form good for viewing.
void Transaction::PrettyPrint(ostream &out) const
{
    out<<"["<<date<<"] $";
    out.precision(2);
    out<<fixed<<amount<<" "<<to<<"\n    <- "<<from;
    if(!comment.empty())
		out<<" ("<<comment<<")";
}



istream &operator>>(istream &in, Transaction &transaction)
{
    in>>transaction.date;
    in>>transaction.amount;
    // Read up to the next tab.
    while(in && in.get() != '\t') {}
    if(in)
    {
		static string line;
		
		getline(in, line);
		size_t length = line.length();
		
		// Find the first tab. It delimits the from field.
		size_t first = line.find('\t');
		if(first == string::npos)
			return in;
		transaction.from = line.substr(0, first);
		
		// Find the second tab.
		size_t second = line.find('\t', first + 1);
		if(second == string::npos)
		{
			second = length;
			transaction.comment.clear();
		}
		else
			transaction.comment = line.substr(second + 1, length - (second + 1));
		transaction.to = line.substr(first + 1, second - (first + 1));
    }
    return in;
}



ostream &operator<<(ostream &out, const Transaction &transaction)
{
	out << transaction.date << '\t';
	out.precision(2);
	out << fixed << transaction.amount << '\t';
	out << transaction.from << '\t' << transaction.to;
	if(!transaction.comment.empty())
		out << '\t' << transaction.comment;
	out << '\n';
	return out;
}
